﻿using System.Collections.Generic;
using System.Linq;
using Game;
using Game.UI;
using Script.Game;
using UnityEngine;
using ZYLFramework.Manage;

public class GameManager : MonoBehaviour
{
    private GameObject Root;
    private UIInit _uiInit;

    public GameObject Camera;
    public GameObject UICamera;

    /// <summary>
    /// 默认输入冷却
    /// </summary>
    private float DefineInputCoolTime = 0.2f;
    
    private float inputCoolTime;

    /// <summary>
    /// 玩家操作状态
    /// </summary>
    private RoundState CurRoundState;

    /// <summary>
    /// 选中的棋子
    /// </summary>
    private GameObject Pawn;

    /// <summary>
    /// 临时保存的当前坐标
    /// </summary>
    private Vector2Int cursorPos;
    
    /// <summary>
    /// 玩家按键
    /// </summary>
    private Dictionary<ControlCommand ,KeyCode> InputType;
    
    /// <summary>
    /// 是否接收玩家按键
    /// </summary>
    private bool AcceptInput = false;
    
    /// <summary>
    /// 玩家按键优先级
    /// </summary>
    private ControlCommand[] PriorityInputType = {ControlCommand.Cancel,ControlCommand.Submit,ControlCommand.Up,ControlCommand.Down,ControlCommand.Left,ControlCommand.Right};
    
    private void Awake()
    {
        gameObject.AddComponent<ResourcesManage>();
        gameObject.AddComponent<EventManage>();
        gameObject.AddComponent<TimelineManager>();
        gameObject.AddComponent<UIManage>();
        gameObject.AddComponent<LevelManager>();
        gameObject.AddComponent<DamageManager>();
        
        
        InputType = new Dictionary<ControlCommand, KeyCode>
        {
            [ControlCommand.Up] = KeyCode.W,
            [ControlCommand.Down] = KeyCode.S,
            [ControlCommand.Left] = KeyCode.A,
            [ControlCommand.Right] = KeyCode.D,
            [ControlCommand.Submit] = KeyCode.F,
            [ControlCommand.Cancel] = KeyCode.Q,
        };

        CurRoundState = GameState.CurRoundState;
    }
    
    // Start is called before the first frame update
    void Start()
    { 
        SceneVariants.RegisterMessageEvent(EventEnum.QuitGame,delegate(object[] objects) { OnExitGame(); });
        SceneVariants.RegisterMessageEvent(EventEnum.RestartGame,delegate(object[] objects) { OpenLevel(10); });
        
        GameState.InitInfo();
        Root = GameObject.Find("Root");
        Camera = GameObject.Find("MainCamera");
        UICamera = GameObject.Find("Canvas/UICamera");
        _uiInit = new UIInit();
        _uiInit.Init();
        InitInputCoolTime();
        UIManage.Instance.Open(UIEnum.TestPanel);
        UIManage.Instance.Open(UIEnum.RoundPanel);
        UIManage.Instance.Open(UIEnum.PawnStatePanel);
        
        OpenLevel(10);
    }

    // Update is called once per frame
    void Update()
    {
        if (inputCoolTime > 0)
        {
            inputCoolTime -= Time.deltaTime;
            inputCoolTime = Mathf.Max(inputCoolTime, 0);
        }
    }
    
    void FixedUpdate()
    {
        SetControlCommand();
    }

    void OpenLevel(int levelId)
    {
        SceneVariants.GetLevelManager().LoadLevel(levelId);
    }
    
    public void SetAcceptInput(bool canAcceptInput)
    {
        AcceptInput = canAcceptInput;
    }
    
    // 退出游戏
    public void OnExitGame()
    {
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#else
            Application.Quit();
#endif
    }
    
    /// <summary>
    /// 设置焦点位置,和焦点地图位置
    /// </summary>
    /// <param name="pos"></param>
    public void SetFocusPos(Vector2Int pos)
    {
        // 判断是否在地图内
        if (CheckGridInPosition(pos))
        {
            // 限制移动模式下的移动 如果是移动模式，且不在可移动区域内,就不变更
            // if (ControlStatus == ControlStatus.Move && !GameState.ShowMoveMapDict.ContainsKey(SelectMap(pos).transform))
            // {
            //     return;
            // }
            GameState.FocusPos = pos;
            GameState.FocusMapTransform = LevelInfoObj.GetMapByPos(pos).transform;
        }
    }
    
    void InitInputCoolTime()
    {
        inputCoolTime = DefineInputCoolTime;
    }
    


    /// <summary>
    /// 设置操作命令
    /// </summary>
    void SetControlCommand()
    {
        // 有效输入
        if (!AcceptInput || inputCoolTime != 0)
        {
            return;
        }
        cursorPos = GameState.FocusPos;
        foreach (var type in PriorityInputType)
        {
            if (Input.GetKey(InputType[type]) && inputCoolTime == 0)
            {
                switch(type){
                    case ControlCommand.Up:
                        MoveInput(Vector2Int.up);
                        break;
                    case ControlCommand.Down:
                        MoveInput(Vector2Int.down);
                        break;
                    case ControlCommand.Left:
                        MoveInput(Vector2Int.left);
                        break;
                    case ControlCommand.Right:
                        MoveInput(Vector2Int.right);
                        break;
                    case ControlCommand.Cancel:
                        CancelInput();
                        break;
                    case ControlCommand.Submit:
                        SubmitInput();
                        break;
                }
                InitInputCoolTime();
            }
        }
        SetFocusPos(cursorPos);
    }
    
    /// <summary>
    /// Cancel输入处理
    /// </summary>
    /// <param name="command"></param>
    void CancelInput()
    {

    }
    
    /// <summary>
    /// Submit输入处理
    /// </summary>
    /// <param name="command"></param>
    void SubmitInput()
    {
        SceneVariants.GetLevelManager().Submit(GameState.FocusPos);
    }

    

    /// <summary>
    /// 移动输入处理
    /// </summary>
    /// <param name="command"></param>
    void MoveInput(Vector2Int direction)
    {
        if (GameState.AttackObjectInfos.Count > 0)
        {
            var v = 0;
            if (direction == Vector2Int.up || direction == Vector2Int.right)
            {
                v = 1;
            }
            else
            {
                v = -1;
            }
            GameState.AttackObjectIndex += v;
            GameState.AttackObjectIndex = Mathf.Clamp(GameState.AttackObjectIndex,0,GameState.AttackObjectInfos.Count-1);
            if (GameState.AttackObjectInfos.Count > 0 && !GameState.AttackObjectInfos[GameState.AttackObjectIndex].Equals(null))
            {
                cursorPos = GameState.AttackObjectInfos[GameState.AttackObjectIndex].Pos;
            } 
        }
        else
        {
            cursorPos += direction;
        }
    }
    
    /// <summary>
    /// 判断这个坐标是否在地图内
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    public bool CheckGridInPosition(Vector2 pos)
    {
        return SceneVariants.GetLevelManager().CheckGridInPosition(pos);
    }

}
